package org.xbl.xchain.sdk.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.TimeZone;

public class GenesisUtils {
    // module name
    public static String AuthModuleName = "auth";

    // StoreKey is string representation of the store key for auth
    public static String AuthStoreKey = "acc";

    // FeeCollectorName the root string for the fee collector account address
    public static String AuthFeeCollectorName = "fee_collector";

    // QuerierRoute is the querier route for acc
    public static String AuthQuerierRoute = AuthStoreKey;

    public static String BankModuleName   = "bank";
    public static String BankQuerierRoute = BankModuleName;
    public static String BankRouterKey = BankModuleName;
    public static String ErrNoInputs            = ErrorMsg.getErrorString(BankModuleName, 1, "no inputs to send transaction");
    public static String ErrNoOutputs           = ErrorMsg.getErrorString(BankModuleName, 2, "no outputs to send transaction");
    public static String ErrInputOutputMismatch = ErrorMsg.getErrorString(BankModuleName, 3, "sum inputs != sum outputs");
    public static String ErrSendDisabled        = ErrorMsg.getErrorString(BankModuleName, 4, "send transactions are disabled");


    public static String GenutilModuleName = "genutil";

    public static String GovModuleName             = "gov";
    public static String GovStoreKey               = GovModuleName;
    public static String GovRouterKey              = GovModuleName;
    public static String GovQuerierRoute           = GovModuleName;
    public static String GovAttributeValueCategory = GovModuleName;
    public static String GovDefaultParamspace      = GovModuleName;

    public static String UpgradeMoudleName = "upgrade";
    public static String ManageMoudleName = "manage";
    public static String MemberModuleName             = "member";
    public static String MemberStoreKey               = MemberModuleName;
    public static String MemberRouterKey              = MemberModuleName;
    public static String MemberQuerierRoute           = MemberModuleName;
    public static String MemberAttributeValueCategory = MemberModuleName;
    public static String MemberDefaultParamspace      = MemberModuleName;

    // ModuleName defines the name of the module
    public static String ParamsModuleName = "params";
    // RouterKey defines the routing key for a ParameterChangeProposal
    public static String ParamsRouterKey = "params";
    public static String ParamsQuerierRoute           = ParamsModuleName;

    public static String PoaModuleName = "poa";
    public static String PoaStoreKey = PoaModuleName;
    public static String PoaQuerierRoute = PoaModuleName;
    public static String PoaRouterKey = PoaModuleName;


    public static String IccpModuleName = "iccp";
    public static String IccpStoreKey = IccpModuleName;
    public static String IccpQuerierRoute = IccpModuleName;
    public static String IccpRouterKey = IccpModuleName;

    // ModuleName is the name of the contract module
    public static String WasmModuleName = "wasm";
    // StoreKey is the string store representation
    public static String WasmStoreKey = WasmModuleName;
    // TStoreKey is the string transient store representation
    public static String WasmTStoreKey = "transient_" + WasmModuleName;
    // QuerierRoute is the querier route for the staking module
    public static String WasmQuerierRoute = WasmModuleName;
    // RouterKey is the msg router key for the staking module
    public static String WasmRouterKey = WasmModuleName;

    public static String CrossModuleName   = "cross";
    public static String CrossQuerierRoute = CrossModuleName;
    public static String CrossRouterKey    = CrossModuleName;
    public static String CrossStoreKey   = CrossModuleName;
    public static String CrossVersion    = "1.0.0";
    public static String CrossChain = "iccp";

    public static String ShareModuleName   = "share";
    public static String ShareQuerierRoute = ShareModuleName;
    public static String ShareRouterKey    = ShareModuleName;
    public static String ShareStoreKey = ShareModuleName;




    public static String DefaultMaxMemoCharacters      = "256";
    public static String DefaultTxSigLimit             = "7";
    public static String DefaultTxSizeCostPerByte      = "10";
    public static String DefaultSigVerifyCostED25519   = "590";
    public static String DefaultSigVerifyCostSecp256k1 = "1000";
    public static String DefaultSigVerifyCostSm2 = "1000";
    public static String DefaultSigVerifyCostGmca = "1000";

    public static String ABCIPubKeyTypeEd25519   = "ed25519";
    public static String ABCIPubKeyTypeSr25519   = "sr25519";
    public static String ABCIPubKeyTypeSecp256k1 = "secp256k1";
    public static String ABCIPubKeyTypeSm2       = "sm2";

    public static SimpleDateFormat DefaultSimpleDateFormat=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS'Z'");
    public static SimpleDateFormat UTCDateFormat=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
    static {UTCDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));}

    public static ObjectMapper Mapper = new ObjectMapper().setPropertyNamingStrategy(com.fasterxml.jackson.databind.PropertyNamingStrategy.SNAKE_CASE);
    public static ObjectMapper SortMapper = Mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS,true);

    public static boolean isStringSliceContain(String[] strings, String string){
        for (String str : strings){
            if (str.equals(string)){
                return true;
            }
        }
        return false;
    }

    /**
     * only 100h, 100m, 100s , 100ms can be tran
     * @return
     */
    public static Duration getDurationByString(String time){
        if (time.contains("ms")){
            int a = Integer.parseInt(time.substring(0,time.length()-2));
            return Duration.ofMillis(a);
        }else if (time.contains("s")) {
            int a = Integer.parseInt(time.substring(0, time.length() - 1));
            return Duration.ofMillis(a * 1000L);
        }else if (time.contains("m")) {
            int a = Integer.parseInt(time.substring(0, time.length() - 1));
            return Duration.ofMinutes(a);
        }else if (time.contains("h")){
            int a = Integer.parseInt(time.substring(0, time.length() - 1));
            return Duration.ofHours(a);
        }else {
            return Duration.ofNanos(0);
        }
    }
}
